// opencv内有异步加载
globalThis.Module = {
  onRuntimeInitialized() {
    // console.log("opencv准备完毕");
  },
};

let cv: any = null;

import("@/renderer/assets/js/opencv.gai.js").then((module) => {
  cv = module.default;
});

export default function textDetection(inputImg) {
  if (!cv) return;

  // 参考 https://zhuanlan.zhihu.com/p/246260817

  // 文本检测

  const canvas = document.createElement("canvas");
  const images = [];
  images.push(canvas);

  const src = cv.imread(inputImg);
  const dst = cv.Mat.zeros(src.rows, src.cols, cv.CV_8UC3);
  const M = cv.getStructuringElement(cv.MORPH_ELLIPSE, new cv.Size(2, 2));
  const anchor = new cv.Point(-1, -1);
  const contours = new cv.MatVector();
  const rectArray = []
  const hierarchy = new cv.Mat();
  const rectangleColor = new cv.Scalar(255, 0, 0);

  const contoursMode = cv.RETR_EXTERNAL; // RETR_EXTERNAL 不嵌套， RETR_CCOMP 嵌套
  const thresh = 150; // 阈值

  //   const low = new cv.Mat(
  //     src.rows,
  //     src.cols,
  //     src.type(),
  //     new cv.Scalar(0, 0, 0, 0)
  //   );
  //   const high = new cv.Mat(
  //     src.rows,
  //     src.cols,
  //     src.type(),
  //     new cv.Scalar(127, 127, 127, 255)
  //   );

  //   cv.inRange(src, low, high, dst);

  cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY, 0);
  cv.threshold(dst, dst, thresh, 255, cv.THRESH_BINARY);
  cv.bitwise_not(dst, dst);

  // 降噪小尺寸文字会缺失

  //   cv.medianBlur(dst, dst, 3);
  //   cv.morphologyEx(
  //     dst,
  //     dst,
  //     cv.MORPH_OPEN,
  //     M,
  //     anchor,
  //     1,
  //     cv.BORDER_CONSTANT,
  //     cv.morphologyDefaultBorderValue()
  //   );

  cv.findContours(
    dst,
    contours,
    hierarchy,
    contoursMode,
    cv.CHAIN_APPROX_SIMPLE
  );

  for (let i = 0; i < contours.size(); ++i) {
    const cnt = contours.get(i);
    const rect = cv.boundingRect(cnt);
    rectArray.push(rect)

    cnt.delete();
  }

  rectArray.sort((a, b) => a.x - b.x)

  function roiImage(mat) {
    // 总宽高 28 * 28
    const size = mat.size()
    const fontWidth = 20
    const fontHeight = 20
    const padding = 4
    let offset = 0

    let newWidth = size.width / size.height * fontHeight

    if (newWidth >= fontWidth) newWidth = fontWidth
    else offset = (fontWidth - newWidth) / 2

    cv.resize(mat, mat, new cv.Size(newWidth, fontHeight), 0, 0, cv.INTER_NEAREST);
    const image = document.createElement("canvas");

    cv.copyMakeBorder(mat, mat, padding, padding, padding + offset, padding + offset, cv.BORDER_CONSTANT, new cv.Scalar(0, 0, 0, 255))

    cv.imshow(image, mat);

    return image;
  }
  
  cv.cvtColor(dst, dst, cv.COLOR_GRAY2RGB, 0);

  for (let i = 0; i < rectArray.length; ++i) {
    const minWidth = 5; // 最小宽度
    const minHeight = 5; // 最小高度
    const rect = rectArray[i];
    const { x, y, width, height } = rect;

    if (width < minWidth || height < minHeight) continue;

    const roiImg = dst.roi(rect);
    
    images.push(roiImage(roiImg));

    const point1 = new cv.Point(x, y);
    const point2 = new cv.Point(x + width, y + height);
    cv.rectangle(dst, point1, point2, rectangleColor, 1, cv.LINE_AA, 0);

    roiImg.delete();
  }

  cv.imshow(canvas, dst);

  src.delete();
  dst.delete();
  contours.delete();
  hierarchy.delete();
  M.delete();
  //   low.delete();
  //   high.delete();

  return images;
}
